package imp

import (
	sqlc "bgs/db/sqlc"
	brandWarehouseGrpc "bgs/grpc/gen/service/brand_warehouse"
	"bgs/grpc/gen/shared/message"
	warehouseService "bgs/service/warehouse"
	"context"
)

/****************************************************************************************/
/*                               brand_warehouse entity of helper                       */
/****************************************************************************************/

func transformBrandWarehouseEntityToPb(v sqlc.BrandWarehouse) *brandWarehouseGrpc.BrandWarehouseEntity {
	return &brandWarehouseGrpc.BrandWarehouseEntity{
		Id:            v.ID,
		Origin:        v.Origin,
		BrandId:       v.BrandID,
		Name:          v.Name,
		Tel:           v.Tel,
		Linkman:       v.Linkman,
		Address:       v.Address,
		Lng:           v.Lng,
		Lat:           v.Lat,
		DeliveryModes: v.DeliveryModes,
		CityCode:      v.CityCode,
		RegionCode:    v.RegionCode,
		Deadline:      v.Deadline,
		StorageMode:   v.StorageMode,
		StoreId:       v.StoreID,
		PStoreId:      v.PStoreID,
		PermissionId:  v.PermissionID,
		RemotePk:      v.RemotePk,
	}
}

func mapBrandWarehouseEntityToPb(list []sqlc.BrandWarehouse, f func(sqlc.BrandWarehouse) *brandWarehouseGrpc.BrandWarehouseEntity) []*brandWarehouseGrpc.BrandWarehouseEntity {
	r := make([]*brandWarehouseGrpc.BrandWarehouseEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                               brand_warehouse entity of cmd                          */
/****************************************************************************************/

// CreateBrandWarehouse 创建品牌仓库+增加sync相关数据
func (s *BrandAPIService) CreateBrandWarehouse(ctx context.Context, req *brandWarehouseGrpc.CreateBrandWarehouseRequest) (res *brandWarehouseGrpc.CreateBrandWarehouseResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_warehouseImp->CreateBrandWarehouse:%v", req)
	res = &brandWarehouseGrpc.CreateBrandWarehouseResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	var brandWarehouse sqlc.BrandWarehouse
	err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
		p := warehouseService.CreateBrandWarehouseParam{
			CreateParamsPtr: &sqlc.CreateBrandWarehouseParams{
				Origin:        req.Origin,
				BrandID:       req.BrandId,
				Name:          req.Name,
				Tel:           req.Tel,
				Linkman:       req.Linkman,
				Address:       req.Address,
				Lng:           req.Lng,
				Lat:           req.Lat,
				DeliveryModes: req.DeliveryModes,
				CityCode:      req.CityCode,
				RegionCode:    req.RegionCode,
				Deadline:      req.Deadline,
				StorageMode:   req.StorageMode,
				StoreID:       req.StoreId,
				PStoreID:      req.PStoreId,
				PermissionID:  req.PermissionId,
			},
		}

		brandWarehouse, err = s.warehouseService.CreateBrandWarehouse(ctx, q, p)

		if err != nil {
			return err
		}
		slog.Info("grpc创建品牌仓库 ok")

		return
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandWarehouse = transformBrandWarehouseEntityToPb(brandWarehouse)
	return
}

// UpdateBrandWarehouse 更新品牌仓库+更新sync相关数据
func (s *BrandAPIService) UpdateBrandWarehouse(ctx context.Context, req *brandWarehouseGrpc.UpdateBrandWarehouseRequest) (res *brandWarehouseGrpc.UpdateBrandWarehouseResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_warehouseImp->UpdateBrandWarehouse:%v", req)
	res = &brandWarehouseGrpc.UpdateBrandWarehouseResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	var brandWarehouse sqlc.BrandWarehouse
	err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {

		brandWarehouse, err = q.GetBrandWarehouse(ctx, req.Id)
		if err != nil {
			return err
		}
		slog.Info("grpc 读取品牌仓库 ok")

		p := warehouseService.UpdateBrandWarehouseParam{
			UpdateParamsPtr: &sqlc.UpdateBrandWarehouseParams{
				ID:            req.Id,
				Name:          req.Name,
				Tel:           req.Tel,
				Linkman:       req.Linkman,
				Address:       req.Address,
				Lng:           req.Lng,
				Lat:           req.Lat,
				DeliveryModes: req.DeliveryModes,
				CityCode:      brandWarehouse.CityCode,
				RegionCode:    brandWarehouse.RegionCode,
				Deadline:      brandWarehouse.Deadline,
				StorageMode:   brandWarehouse.StorageMode,
				StoreID:       req.StoreId,
				PStoreID:      req.PStoreId,
				PermissionID:  req.PermissionId,
			},
		}

		brandWarehouse, err = s.warehouseService.UpdateBrandWarehouse(ctx, q, p)
		slog.Info("grpc 更新品牌仓库 ok")
		return
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandWarehouse = transformBrandWarehouseEntityToPb(brandWarehouse)
	return
}

/****************************************************************************************/
/*                               brand_warehouse entity of query                            */
/****************************************************************************************/

// GetBrandWarehouse 获取单个品牌仓库
func (s *BrandAPIService) GetBrandWarehouse(ctx context.Context, req *brandWarehouseGrpc.GetBrandWarehouseRequest) (res *brandWarehouseGrpc.GetBrandWarehouseResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_warehouseImp->GetBrandWarehouse:%v", req)
	res = &brandWarehouseGrpc.GetBrandWarehouseResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	BrandWarehouse, err := s.dao.Q.GetBrandWarehouse(ctx, req.Id)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandWarehouse = transformBrandWarehouseEntityToPb(BrandWarehouse)
	return
}

// ListBrandWarehousesByBrandID  根据品牌ID获取品牌仓库列表
func (s *BrandAPIService) ListBrandWarehousesByBrandID(ctx context.Context, req *brandWarehouseGrpc.ListBrandWarehousesByBrandIDRequest) (res *brandWarehouseGrpc.ListBrandWarehousesByBrandIDResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_warehouseImp->ListBrandWarehousesByBrandID:%v", req)

	res = &brandWarehouseGrpc.ListBrandWarehousesByBrandIDResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	total, err := s.dao.Q.CountBrandWarehousesByBrandID(ctx, req.BrandId)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	if total == 0 {
		// 不用继续调用listfunc
		return
	}
	arg := sqlc.ListBrandWarehousesByBrandIDParams{
		Limit:   req.Limit,
		Offset:  req.Offset,
		BrandID: req.BrandId,
	}
	BrandWarehousess, err := s.dao.Q.ListBrandWarehousesByBrandID(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.BrandWarehouses = mapBrandWarehouseEntityToPb(BrandWarehousess, transformBrandWarehouseEntityToPb)
	return
}
